#!/bin/bash

# ========================================
# Java应用启动/重启脚本
# 使用方法: ./restart-java-app
# ========================================

# 全局配置
JAR_NAME=""                         # JAR文件名（为空时自动检测）
JAVA_OPTS=""                        # JVM参数（为空时使用默认值，节省内存）
LOG_FILE=""                         # 日志文件名（自动生成）

# 运行时配置常�?
STOP_TIMEOUT=15                     # 停止超时时间（秒�?
STARTUP_WAIT=3                      # 启动等待时间（秒�?
FORCE_KILL_WAIT=2                   # 强制终止等待时间（秒�?

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# 全局变量（用于交互式选择和批量操作）
SELECTED_JARS=()                    # 用户选择的JAR包数�?
MULTI_JAR_MODE=false                # 是否为多JAR包模�?
PARSED_ACTION=""                    # 解析出的操作命令
PARSED_JARS=()                      # 解析出的JAR包列�?

# ========================================
# 工具函数
# ========================================

# 打印错误消息
print_error() {
    echo -e "${RED}错误: $1${NC}" >&2
}

# 打印警告消息
print_warning() {
    echo -e "${YELLOW}警告: $1${NC}"
}

# 打印成功消息
print_success() {
    echo -e "${GREEN}成功: $1${NC}"
}

# 打印信息消息
print_info() {
    echo -e "${BLUE}$1${NC}"
}

# 验证Java环境的详细检�?
validate_java_environment() {
    # 检查Java是否安装
    if ! command -v java >/dev/null 2>&1; then
        print_error "Java未安装或不在PATH中"
        print_info "请安装Java运行环境（JRE）或Java开发工具包（JDK）"
        return 1
    fi
    
    # 检查Java版本
    local java_version
    java_version=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2)
    
    if [ -z "$java_version" ]; then
        print_error "无法获取Java版本信息"
        return 1
    fi
    
    print_info "检测到Java版本: $java_version"
    
    # 检查Java是否能正常运�?
    if ! java -version >/dev/null 2>&1; then
        print_error "Java环境异常，无法正常运行"
        return 1
    fi
    
    return 0
}

# 检查磁盘空�?
check_disk_space() {
    local required_space_mb="${1:-100}"  # 默认需要100MB空间
    
    # 获取当前目录的可用空间（MB�?
    local available_space
    if command -v df >/dev/null 2>&1; then
        available_space=$(df . | awk 'NR==2 {print int($4/1024)}')
        
        if [ "$available_space" -lt "$required_space_mb" ]; then
            print_warning "磁盘空间不足，可用空间 ${available_space}MB，建议至少 ${required_space_mb}MB"
            return 1
        fi
    else
        print_warning "无法检查磁盘空间（df命令不可用）"
    fi
    
    return 0
}

# 检查文件权�?
check_file_permissions() {
    local file_path="$1"
    
    # 检查文件是否存�?
    if [ ! -f "$file_path" ]; then
        print_error "文件不存在: $file_path"
        return 1
    fi
    
    # 检查文件是否可�?
    if [ ! -r "$file_path" ]; then
        print_error "文件不可读: $file_path"
        return 1
    fi
    
    return 0
}

# 验证JAR文件名的安全�?
validate_jar_name() {
    local jar_name="$1"
    
    # 检查是否为�?
    if [ -z "$jar_name" ]; then
        print_error "JAR文件名不能为空"
        return 1
    fi
    
    # 检查文件名长度（防止过长的文件名）
    if [ ${#jar_name} -gt 255 ]; then
        print_error "JAR文件名过长（超过255个字符）"
        return 1
    fi
    
    # 检查是否包含危险字符（路径遍历攻击�?
    if [[ "$jar_name" == *".."* ]] || [[ "$jar_name" == *"/"* ]] || [[ "$jar_name" == *"\\"* ]]; then
        print_error "JAR文件名包含非法字符（不允许路径分隔符或相对路径）"
        return 1
    fi
    
    # 检查是否以.jar结尾
    if [[ ! "$jar_name" == *.jar ]]; then
        print_error "文件必须是jar格式"
        return 1
    fi
    
    # 检查文件名是否包含特殊字符（可能导致命令注入）
    if [[ "$jar_name" =~ [\;\|\&\$\`\<\>\(\)\{\}\[\]\"\'*\?\~] ]]; then
        print_error "JAR文件名包含特殊字符，可能存在安全风险"
        return 1
    fi
    
    return 0
}

# 验证用户输入的安全�?
validate_user_input() {
    local input="$1"
    local input_type="${2:-general}"
    
    # 检查输入长�?
    if [ ${#input} -gt 1000 ]; then
        print_error "输入内容过长"
        return 1
    fi
    
    # 根据输入类型进行不同的验�?
    case "$input_type" in
        "number")
            # 验证数字输入
            if [[ ! "$input" =~ ^[0-9,[:space:]]+$ ]] && [ "$input" != "all" ]; then
                print_error "输入格式错误，只允许数字、逗号、空格或'all'"
                return 1
            fi
            ;;
        "action")
            # 验证操作命令
            if [[ ! "$input" =~ ^(start|stop|restart|status|help|-h|--help)$ ]]; then
                print_error "无效的操作命令: $input"
                return 1
            fi
            ;;
        "general")
            # 通用输入验证，检查危险字�?
            if [[ "$input" =~ [\;\|\&\$\`\<\>\(\)\{\}*\?\~] ]]; then
                print_error "输入包含特殊字符，可能存在安全风险"
                return 1
            fi
            ;;
    esac
    
    return 0
}

# 检查Java环境
check_java_environment() {
    if ! command -v java &> /dev/null; then
        print_error "Java未安装或不在PATH中"
        return 1
    fi
    
    # 使用更详细的Java环境验证
    if ! validate_java_environment; then
        return 1
    fi
    
    # 检查磁盘空�?
    if ! check_disk_space; then
        print_warning "磁盘空间不足可能影响应用运行"
    fi
    
    return 0
}

# 设置JAR包相关变�?
setup_jar_variables() {
    local jar_name="$1"
    
    if [ -z "$jar_name" ]; then
        jar_name="$JAR_NAME"
    fi
    
    # 设置日志文件名（只使用时间戳�?
    local jar_basename=$(basename "$jar_name" .jar)
    local timestamp=$(date +"%Y%m%d_%H%M%S")
    
    # 创建日志目录结构：log/jar包名�?
    local log_dir="log/${jar_basename}"
    
    # 确保日志目录存在
    if [ ! -d "$log_dir" ]; then
        mkdir -p "$log_dir" 2>/dev/null
        if [ $? -ne 0 ]; then
            print_warning "无法创建日志目录 $log_dir，使用当前目录"
            LOG_FILE="${timestamp}.log"
        else
            LOG_FILE="${log_dir}/${timestamp}.log"
        fi
    else
        LOG_FILE="${log_dir}/${timestamp}.log"
    fi
}

# 等待进程停止
wait_for_process_stop() {
    local pid="$1"
    local timeout="${2:-$STOP_TIMEOUT}"
    local count=0
    
    while [ $count -lt $timeout ]; do
        if ! ps -p $pid > /dev/null 2>&1; then
            return 0
        fi
        sleep 1
        count=$((count + 1))
    done
    return 1
}

# 根据昵称匹配JAR文件
find_jar_by_nickname() {
    local nickname="$1"
    local found_jars=()
    
    # 如果昵称是"all"，返回所有JAR文件
    if [ "$nickname" = "all" ]; then
        for jar in *.jar; do
            if [ -f "$jar" ]; then
                found_jars+=("$jar")
            fi
        done
    else
        # 模糊匹配JAR文件�?
        for jar in *.jar; do
            if [ -f "$jar" ] && [[ "$jar" == *"$nickname"* ]]; then
                found_jars+=("$jar")
            fi
        done
    fi
    
    # 输出匹配的JAR文件
    printf '%s\n' "${found_jars[@]}"
}

# 解析JAR包参数列�?
parse_jar_arguments() {
    local args=("$@")
    local jar_list=()
    local action=""
    
    # 如果没有参数，使用默认行�?
    if [ ${#args[@]} -eq 0 ]; then
        action="restart"
        PARSED_ACTION="$action"
        return
    fi
    
    # 检查第一个参数是否是操作命令
    case "${args[0]}" in
        "start"|"stop"|"restart"|"status"|"help"|"-h"|"--help")
            action="${args[0]}"
            
            # 验证操作命令
            if ! validate_user_input "$action" "action"; then
                return 1
            fi
            
            # 如果只有操作命令，使用原有逻辑
            if [ ${#args[@]} -eq 1 ]; then
                PARSED_ACTION="$action"
                return
            fi
            # 其余参数作为JAR包昵�?
            for ((i=1; i<${#args[@]}; i++)); do
                # 验证JAR包昵称输�?
                if ! validate_user_input "${args[i]}" "general"; then
                    return 1
                fi
                jar_list+=("${args[i]}")
            done
            ;;
        *)
            # 第一个参数不是操作命令，默认为restart操作
            action="restart"
            # 所有参数都作为JAR包昵�?
            for arg in "${args[@]}"; do
                # 验证JAR包昵称输�?
                if ! validate_user_input "$arg" "general"; then
                    return 1
                fi
                jar_list+=("$arg")
            done
            ;;
    esac
    
    # 设置全局变量
    PARSED_ACTION="$action"
    PARSED_JARS=("${jar_list[@]}")
}

# 检查JAR文件是否存在
check_jar_exists() {
    # 如果JAR_NAME为空，自动检测当前目录下的JAR文件
    if [ -z "$JAR_NAME" ]; then
        local jar_files=(*.jar)
        
        # 检查是否存在JAR文件
        if [ ! -e "${jar_files[0]}" ]; then
            print_error "当前目录下没有找到JAR文件！"
        print_warning "请将JAR文件放在脚本同一目录下，或在脚本中指定JAR_NAME"
            return 1
        fi
        
        # 如果只有一个JAR文件，自动使�?
        if [ ${#jar_files[@]} -eq 1 ]; then
            JAR_NAME="${jar_files[0]}"
            
            # 验证JAR文件名的安全�?
            if ! validate_jar_name "$JAR_NAME"; then
                return 1
            fi
            
            print_info "自动检测到JAR文件: $JAR_NAME"
        else
            # 多个JAR文件时，让用户选择
            print_info "检测到多个JAR文件，请选择要启动的应用："
            echo ""
            
            # 显示选项列表
            local i=1
            for jar in "${jar_files[@]}"; do
                echo -e "${GREEN}[$i]${NC} $jar"
                ((i++))
            done
            echo ""
            
            # 提示用户输入
            echo -e "${YELLOW}输入选项:${NC}"
            echo -e "  - 单个序号: ${GREEN}1${NC} (选择一个JAR包)"
            echo -e "  - 多个序号: ${GREEN}1,3,5${NC} 或 ${GREEN}1 3 5${NC} (选择多个JAR包)"
            echo -e "  - 全部选择: ${GREEN}all${NC} (选择所有JAR包)"
            echo ""
            echo -n -e "${YELLOW}请输入选择: ${NC}"
            read -r choice
            
            # 验证用户输入
            if ! validate_user_input "$choice" "number"; then
                return 1
            fi
            
            # 处理输入
            local selected_jars=()
            
            if [ "$choice" = "all" ]; then
                # 选择所有JAR�?
                selected_jars=("${jar_files[@]}")
                print_success "已选择所有JAR包(${#selected_jars[@]}个)"
            else
                # 解析序号输入（支持逗号分隔和空格分隔）
                local numbers
                if [[ "$choice" == *","* ]]; then
                    # 逗号分隔
                    IFS=',' read -ra numbers <<< "$choice"
                else
                    # 空格分隔
                    read -ra numbers <<< "$choice"
                fi
                
                # 验证并收集选中的JAR�?
                local valid_selection=true
                for num in "${numbers[@]}"; do
                    # 去除空格
                    num=$(echo "$num" | tr -d ' ')
                    
                    if [[ "$num" =~ ^[0-9]+$ ]] && [ "$num" -ge 1 ] && [ "$num" -le ${#jar_files[@]} ]; then
                        selected_jars+=("${jar_files[$((num-1))]}")
                    else
                        print_error "无效的序号 '$num'！请输入1到${#jar_files[@]}之间的数字"
                        valid_selection=false
                        break
                    fi
                done
                
                if [ "$valid_selection" = false ]; then
                    return 1
                fi
                
                # 去重
                selected_jars=($(printf '%s\n' "${selected_jars[@]}" | sort -u))
                
                print_success "已选择 ${#selected_jars[@]} 个JAR包"
                for jar in "${selected_jars[@]}"; do
                    echo -e "  - $jar"
                done
            fi
            
            # 验证所有选中的JAR文件�?
            for jar in "${selected_jars[@]}"; do
                if ! validate_jar_name "$jar"; then
                    return 1
                fi
            done
            
            echo ""
            
            # 如果选择了多个JAR包，设置全局变量供批量操作使�?
            if [ ${#selected_jars[@]} -gt 1 ]; then
                SELECTED_JARS=("${selected_jars[@]}")
                MULTI_JAR_MODE=true
                # 设置第一个JAR作为默认JAR_NAME（兼容性）
                JAR_NAME="${selected_jars[0]}"
            else
                # 单个JAR�?
                JAR_NAME="${selected_jars[0]}"
                MULTI_JAR_MODE=false
            fi
        fi
    fi
    
    # 检查指定的JAR文件是否存在
    if [ ! -f "$JAR_NAME" ]; then
        print_error "JAR文件 '$JAR_NAME' 不存在！"
        print_warning "请检查JAR_NAME配置是否正确，或确保JAR文件在当前目录下"
        return 1
    fi
    
    # 检查文件权�?
    if ! check_file_permissions "$JAR_NAME"; then
        return 1
    fi
    
    return 0
}

# 获取运行中的应用PID
get_app_pid() {
    local jar_name="$1"
    
    if [ -z "$jar_name" ]; then
        jar_name="$JAR_NAME"
    fi
    
    # 通过进程名查找（更可靠的方法�?
    pgrep -f "$jar_name" | head -1
}

# 获取应用占用的端口号
get_app_ports() {
    local pid="$1"
    
    if [ -z "$pid" ]; then
        return 1
    fi
    
    # 使用 ss 命令获取进程占用的端�?
    local ports=()
    
    # 检�?ss 命令是否可用
    if ! command -v ss >/dev/null 2>&1; then
        # 如果 ss 不可用，尝试使用 netstat
        if command -v netstat >/dev/null 2>&1; then
            # 使用 netstat 作为备选方�?
            local netstat_output
            netstat_output=$(netstat -tlnp 2>/dev/null | grep "$pid/" | awk '{print $4}' | sed 's/.*://' | sort -n | uniq)
            if [ -n "$netstat_output" ]; then
                while IFS= read -r port; do
                    if [[ "$port" =~ ^[0-9]+$ ]]; then
                        ports+=("$port")
                    fi
                done <<< "$netstat_output"
            fi
        fi
    else
        # 使用 ss 命令获取 TCP 监听端口
        local ss_output
        ss_output=$(ss -tlnp 2>/dev/null | grep "pid=$pid," | awk '{print $4}' | sed 's/.*://' | sort -n | uniq)
        if [ -n "$ss_output" ]; then
            while IFS= read -r port; do
                if [[ "$port" =~ ^[0-9]+$ ]]; then
                    ports+=("$port")
                fi
            done <<< "$ss_output"
        fi
        
        # 同时获取 UDP 端口（如果需要）
        local ss_udp_output
        ss_udp_output=$(ss -ulnp 2>/dev/null | grep "pid=$pid," | awk '{print $4}' | sed 's/.*://' | sort -n | uniq)
        if [ -n "$ss_udp_output" ]; then
            while IFS= read -r port; do
                if [[ "$port" =~ ^[0-9]+$ ]]; then
                    # 检查是否已存在，避免重�?
                    local exists=false
                    for existing_port in "${ports[@]}"; do
                        if [ "$existing_port" = "$port" ]; then
                            exists=true
                            break
                        fi
                    done
                    if [ "$exists" = false ]; then
                        ports+=("$port")
                    fi
                fi
            done <<< "$ss_udp_output"
        fi
    fi
    
    # 输出端口列表
    if [ ${#ports[@]} -gt 0 ]; then
        printf '%s\n' "${ports[@]}"
        return 0
    else
        return 1
    fi
}

# 检查应用是否正在运�?
is_running() {
    local jar_name="$1"
    local pid=$(get_app_pid "$jar_name")
    
    if [ -n "$pid" ]; then
        return 0  # 正在运行
    else
        return 1  # 未运�?
    fi
}

# 启动应用
start_app() {
    local jar_name="$1"
    
    if [ -z "$jar_name" ]; then
        jar_name="$JAR_NAME"
    fi
    
    if ! check_java_environment; then
        return 1
    fi
    
    setup_jar_variables "$jar_name"
    
    if is_running "$jar_name"; then
        print_warning "应用 $jar_name 已在运行中(PID: $(get_app_pid "$jar_name"))"
        return 0
    fi
    
    print_info "正在启动应用: $jar_name"
    print_info "日志文件: $LOG_FILE"
    
    # 启动应用
    nohup java $JAVA_OPTS -jar "$jar_name" > "$LOG_FILE" 2>&1 &
    
    # 等待启动
    sleep "$STARTUP_WAIT"
    
    # 验证启动状�?
    if is_running "$jar_name"; then
        local actual_pid=$(get_app_pid "$jar_name")
        print_success "应用 $jar_name 启动成功 (PID: $actual_pid)"
        print_info "查看日志: tail -f $LOG_FILE"
        return 0
    else
        print_error "应用 $jar_name 启动失败"
        print_warning "请检查日志文件: $LOG_FILE"
        return 1
    fi
}

# 停止应用
stop_app() {
    local jar_name="$1"
    
    if [ -z "$jar_name" ]; then
        jar_name="$JAR_NAME"
    fi
    
    local pid=$(get_app_pid "$jar_name")
    
    if [ -z "$pid" ]; then
        print_warning "应用 $jar_name 未运行"
        return 0
    fi
    
    setup_jar_variables "$jar_name"
    
    print_info "正在停止应用 $jar_name (PID: $pid)..."
    
    # 发送TERM信号
    kill "$pid" 2>/dev/null
    
    # 等待进程停止
    if wait_for_process_stop "$pid"; then
        print_success "应用 $jar_name 已成功停止"
        return 0
    else
        print_warning "应用 $jar_name 未在 ${STOP_TIMEOUT} 秒内停止，强制终止..."
        kill -9 "$pid" 2>/dev/null
        sleep "$FORCE_KILL_WAIT"
        
        # 再次检�?
        if [ -z "$(get_app_pid "$jar_name")" ]; then
            print_success "应用 $jar_name 已强制停止"
            return 0
        else
            print_error "无法停止应用 $jar_name"
            return 1
        fi
    fi
}

# 重启应用
restart_app() {
    local jar_name="$1"
    
    if [ -z "$jar_name" ]; then
        jar_name="$JAR_NAME"
    fi
    
    if ! check_java_environment; then
        return 1
    fi
    
    setup_jar_variables "$jar_name"
    
    print_info "正在重启应用: $jar_name"
    
    if is_running "$jar_name"; then
        print_info "正在停止应用..."
        stop_app "$jar_name"
    else
        print_info "应用未运行，直接启动"
    fi
    
    print_info "正在启动应用..."
    start_app "$jar_name"
}

# 显示应用状�?
show_status() {
    local jar_name="$1"
    
    if [ -z "$jar_name" ]; then
        jar_name="$JAR_NAME"
    fi
    
    setup_jar_variables "$jar_name"
    
    print_info "=== 应用状态 ==="
    echo "JAR包: $jar_name"
    echo "JVM参数: $JAVA_OPTS"
    echo "日志文件: $LOG_FILE"
    echo ""
    
    local pid=$(get_app_pid "$jar_name")
    
    if [ -n "$pid" ]; then
        print_success "✓ 应用正在运行 (PID: $pid)"
        
        # 获取并显示端口信�?
        echo ""
        echo "端口信息:"
        local ports
        ports=$(get_app_ports "$pid")
        if [ $? -eq 0 ] && [ -n "$ports" ]; then
            echo "  监听端口:"
            while IFS= read -r port; do
                echo "    - $port"
            done <<< "$ports"
        else
            echo "  未检测到监听端口"
        fi
        
        # 显示进程信息
        if command -v ps >/dev/null 2>&1; then
            echo ""
            echo "进程详情:"
            ps -p "$pid" -o pid,ppid,cmd --no-headers 2>/dev/null || echo "  无法获取进程详情"
        fi
    else
        print_warning "✗ 应用未运行"
    fi
}

# 批量启动应用
batch_start_app() {
    local jar_files=("$@")
    local success_count=0
    local total_count=${#jar_files[@]}
    
    if [ $total_count -eq 0 ]; then
        print_error "没有指定要启动的JAR包"
        return 1
    fi
    
    if ! check_java_environment; then
        return 1
    fi
    
    print_info "=== 批量启动应用 ==="
    print_info "准备启动 $total_count 个JAR包..."
    echo ""
    
    for jar_file in "${jar_files[@]}"; do
        print_info "正在启动: $jar_file"
        
        # 检查JAR文件是否存在
        if [ ! -f "$jar_file" ]; then
            print_error "  JAR文件不存在: $jar_file"
            continue
        fi
        
        setup_jar_variables "$jar_file"
        
        # 检查是否已经在运行
        if is_running "$jar_file"; then
            print_warning "  $jar_file 已经在运行"
            ((success_count++))
            continue
        fi
        
        # 启动应用
        echo "  JAR包: $jar_file"
        echo "  JVM参数: $JAVA_OPTS"
        echo "  日志文件: $LOG_FILE"
        
        nohup java $JAVA_OPTS -jar "$jar_file" > "$LOG_FILE" 2>&1 &
        
        sleep "$STARTUP_WAIT"
        
        if is_running "$jar_file"; then
            local pid=$(get_app_pid "$jar_file")
            print_success "  $jar_file 启动成功 (PID: $pid)"
            ((success_count++))
        else
            print_error "  $jar_file 启动失败"
            print_warning "    请检查日志文件: $LOG_FILE"
        fi
        echo ""
    done
    
    print_info "=== 批量启动完成 ==="
    if [ $success_count -eq $total_count ]; then
        print_success "成功启动: $success_count/$total_count"
    else
        print_warning "成功启动: $success_count/$total_count"
    fi
}

# 批量停止应用
batch_stop_app() {
    local jar_files=("$@")
    local success_count=0
    local total_count=${#jar_files[@]}
    
    if [ $total_count -eq 0 ]; then
        print_error "没有指定要停止的JAR包"
        return 1
    fi
    
    print_info "=== 批量停止应用 ==="
    print_info "准备停止 $total_count 个JAR包..."
    echo ""
    
    for jar_file in "${jar_files[@]}"; do
        print_info "正在停止: $jar_file"
        
        local pid=$(get_app_pid "$jar_file")
        
        if [ -z "$pid" ]; then
            print_warning "  $jar_file 未运行"
            ((success_count++))
            continue
        fi
        
        setup_jar_variables "$jar_file"
        
        echo "  正在停止进程 (PID: $pid)..."
        kill "$pid" 2>/dev/null
        
        # 等待进程停止
        if wait_for_process_stop "$pid"; then
            print_success "  $jar_file 停止成功"
            ((success_count++))
        else
            print_warning "  强制停止进程..."
            kill -9 "$pid" 2>/dev/null
            sleep "$FORCE_KILL_WAIT"
            
            if [ -z "$(get_app_pid "$jar_file")" ]; then
                print_success "  $jar_file 强制停止成功"
                ((success_count++))
            else
                print_error "  $jar_file 停止失败"
            fi
        fi
        echo ""
    done
    
    print_info "=== 批量停止完成 ==="
    if [ $success_count -eq $total_count ]; then
        print_success "成功停止: $success_count/$total_count"
    else
        print_warning "成功停止: $success_count/$total_count"
    fi
}

# 批量重启应用
batch_restart_app() {
    local jar_files=("$@")
    
    if [ ${#jar_files[@]} -eq 0 ]; then
        print_error "没有指定要重启的JAR包"
        return 1
    fi
    
    if ! check_java_environment; then
        return 1
    fi
    
    print_info "=== 批量重启应用 ==="
    print_info "准备重启 ${#jar_files[@]} 个JAR包..."
    echo ""
    
    # 先停止所有应�?
    batch_stop_app "${jar_files[@]}"
    
    echo ""
    sleep "$STARTUP_WAIT"
    
    # 再启动所有应�?
    batch_start_app "${jar_files[@]}"
}

# 批量显示状�?
batch_show_status() {
    local jar_files=("$@")
    
    if [ ${#jar_files[@]} -eq 0 ]; then
        print_error "没有指定要查看状态的JAR包"
        return 1
    fi
    
    print_info "=== 批量应用状态 ==="
    echo ""
    
    local running_count=0
    local total_count=${#jar_files[@]}
    
    for jar_file in "${jar_files[@]}"; do
        echo -e "${CYAN}--- $jar_file ---${NC}"
        
        setup_jar_variables "$jar_file"
        
        echo "JAR包: $jar_file"
        echo "JVM参数: $JAVA_OPTS"
        echo "日志文件: $LOG_FILE"
        
        local pid=$(get_app_pid "$jar_file")
        
        if [ -n "$pid" ]; then
            print_success "✓ 正在运行 (PID: $pid)"
            ((running_count++))
        else
            print_warning "✗ 未运行"
        fi
        echo ""
    done
    
    print_info "=== 状态统计 ==="
    if [ $running_count -eq $total_count ]; then
        print_success "运行中: $running_count/$total_count (全部运行)"
    elif [ $running_count -eq 0 ]; then
        print_warning "运行中: $running_count/$total_count (全部停止)"
    else
        print_warning "运行中: $running_count/$total_count (部分运行)"
    fi
}

# 显示帮助信息
show_help() {
    cat << 'EOF'
Java应用管理脚本

用法:
  ./restart-java-app {start|stop|restart|status|help} [jar昵称1] [jar昵称2] ...
  ./restart-java-app [jar昵称1] [jar昵称2] ...  # 默认执行restart操作

命令说明:
  start    - 启动应用
  stop     - 停止应用
  restart  - 重启应用（默认操作）
  status   - 查看应用状�?
  help     - 显示帮助信息

JAR包昵称说�?
  �?支持模糊匹配：输入JAR包名称的一部分即可匹配
  �?支持多个昵称：可以同时指定多个JAR包昵称进行批量操�?
  �?支持 'all' 参数：使�?'all' 可以对所有JAR包进行操�?
  �?自动检测：如果不指定昵称，脚本会自动检测当前目录下的JAR�?

使用示例:
  ./restart-java-app start                    # 启动（自动检测JAR包）
  ./restart-java-app restart myapp            # 重启包含"myapp"的JAR包
  ./restart-java-app status user-service      # 查看user-service状�?

批量操作:
  ./restart-java-app start user order         # 启动user和order相关的JAR�?
  ./restart-java-app stop all                 # 停止所有JAR�?
  ./restart-java-app restart user order pay   # 重启多个服务

简化用法（默认restart�?
  ./restart-java-app myapp                    # 重启myapp
  ./restart-java-app user order               # 重启user和order服务

配置说明:
  �?JAR_NAME: JAR文件名（留空自动检测）
  �?JAVA_OPTS: JVM参数（默认为空，使用系统默认设置�?
  �?日志文件: 自动生成�?log/{jar名称}/{时间戳}.log

注意事项:
  �?脚本需要在JAR文件所在目录运�?
  �?确保有足够的权限启动/停止进程
  �?日志文件会在同一目录下生�?
  �?支持优雅停止，超时后会强制终止进�?
EOF
}

# 执行命令的统一处理函数
execute_command() {
    local action="$1"
    shift
    local jar_files=("$@")
    
    case "$action" in
        "start")
            if [ ${#jar_files[@]} -gt 1 ]; then
                batch_start_app "${jar_files[@]}"
            else
                start_app "${jar_files[0]}"
            fi
            ;;
        "stop")
            if [ ${#jar_files[@]} -gt 1 ]; then
                batch_stop_app "${jar_files[@]}"
            else
                stop_app "${jar_files[0]}"
            fi
            ;;
        "restart")
            if [ ${#jar_files[@]} -gt 1 ]; then
                batch_restart_app "${jar_files[@]}"
            else
                restart_app "${jar_files[0]}"
            fi
            ;;
        "status")
            if [ ${#jar_files[@]} -gt 1 ]; then
                batch_show_status "${jar_files[@]}"
            else
                show_status "${jar_files[0]}"
            fi
            ;;
        "help"|"-h"|"--help")
            show_help
            ;;
        *)
            print_error "未知命令 '$action'"
            show_help
            exit 1
            ;;
    esac
}

# ========================================
# 主程�?
# ========================================

# 解析命令行参�?
parse_jar_arguments "$@"

# 如果解析出了JAR包参数，执行批量操作
if [ ${#PARSED_JARS[@]} -gt 0 ]; then
    # 收集所有匹配的JAR文件
    all_jar_files=()
    
    for nickname in "${PARSED_JARS[@]}"; do
        matched_jars=($(find_jar_by_nickname "$nickname"))
        
        if [ ${#matched_jars[@]} -eq 0 ]; then
            print_error "未找到匹配昵称'$nickname' 的JAR文件"
            exit 1
        fi
        
        # 添加到总列�?
        all_jar_files+=("${matched_jars[@]}")
    done
    
    # 去重
    unique_jars=($(printf '%s\n' "${all_jar_files[@]}" | sort -u))
    
    print_info "找到 ${#unique_jars[@]} 个JAR文件:"
    for jar in "${unique_jars[@]}"; do
        echo "  - $jar"
    done
    echo ""
    
    execute_command "$PARSED_ACTION" "${unique_jars[@]}"
else
    # 检查JAR文件是否存在（可能触发交互式选择�?
    if ! check_jar_exists; then
        exit 1
    fi
    
    # 处理命令行参�?
    ACTION="${PARSED_ACTION:-restart}"
    
    # 检查是否在check_jar_exists中选择了多个JAR�?
    if [ "$MULTI_JAR_MODE" = true ] && [ ${#SELECTED_JARS[@]} -gt 0 ]; then
        print_info "检测到多JAR包模式，将对 ${#SELECTED_JARS[@]} 个JAR包执行'$ACTION' 操作"
        echo ""
        
        execute_command "$ACTION" "${SELECTED_JARS[@]}"
    else
        # 单JAR包操�?
        execute_command "$ACTION" "$JAR_NAME"
    fi
fi